package com.heima.wemedia.scan.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.aliyun.AliyunGreenTemplate;
import com.heima.clients.ArticleFeignClient;
import com.heima.file.MinIOTemplate;
import com.heima.model.article.dto.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.entity.WmChannel;
import com.heima.model.wemedia.entity.WmNews;
import com.heima.model.wemedia.entity.WmUser;
import com.heima.utils.common.SensitiveWordUtil;
import com.heima.wemedia.scan.dao.WmChannelDao;
import com.heima.wemedia.scan.dao.WmNewsDao;
import com.heima.wemedia.scan.dao.WmUserDao;
import com.heima.wemedia.scan.service.WmNewsAutoScanService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {

    @Autowired
    private WmNewsDao wmNewsDao;
    @Autowired
    private AliyunGreenTemplate aliyunGreenTemplate;
    @Autowired
    private MinIOTemplate minIOTemplate;

    @Autowired
    private WmUserDao wmUserDao;

    @Autowired
    private WmChannelDao wmChannelDao;

    @Resource
    private ArticleFeignClient articleFeignClient;

    @Override
    public void autoScanNews(Long newsId) {
        //判断文章内容是否存在
        WmNews wmNews = wmNewsDao.queryById(newsId);
        if (wmNews == null) {
            throw new RuntimeException("文章数据不存在");
        }
        //审核失败或者未上架的文章均可以再次编辑,重新进行审核,状态为1
        if (wmNews.getStatus() != 1) {
            return;
        }

        //调用封装文本与图片方法
        Map<String, Object> map = extractTextAndImages(wmNews);
        //内容审核
        String text = (String) map.get("text");

        //调用自定义敏感词审核
        boolean sensitiveResult = handleSensitiveScan(wmNews, text);
        if (!sensitiveResult) {
            return;
        }


        boolean result = handleTextScan(wmNews, text);
        //审核不通过,已经改变过审核信息表了 所以return
        if (!result) {
            return;
        }

        List<String> images = (List<String>) map.get("image");
        boolean rresult = handleImagesScan(wmNews, images);

        if(!rresult){
            return;
        }

        //4. 审核通过, 修改文章状态
        //4.1 如果还没到用户设置的发布时间 , 修改文章状态为8即可
        if (wmNews.getPublishTime().getTime() > System.currentTimeMillis()) {
            updateStatus(wmNews, (short) 8, "审核通过");
            return;
        }

        //4.2 如果已经到了用户设置的发布时间, 需要修改文章状态为9 , 并且发布文章
        saveArticle(wmNews);
    }


    /**
     * 审核通过发布文章
     *
     * @param wmNews
     */
    @Override
    public ResponseResult saveArticle(WmNews wmNews) {
        //1. 封装参数
        ArticleDto articleDto = new ArticleDto();
        BeanUtils.copyProperties(wmNews, articleDto);

        //处理数据  id  authorId authorName  channelName  layout
        articleDto.setNewsId(wmNews.getId());

        articleDto.setAuthorId(wmNews.getUserId().longValue());
        WmUser wmUser = wmUserDao.queryById(wmNews.getUserId());
        if (wmUser != null) {
            articleDto.setAuthorName(wmUser.getNickname());
        }

        WmChannel wmChannel = wmChannelDao.queryById(wmNews.getChannelId());
        if (wmChannel != null) {
            articleDto.setChannelName(wmChannel.getName());
        }

        articleDto.setLayout((int) wmNews.getType());

        //2. 调用远程feign接口发布文章
        ResponseResult responseResult = articleFeignClient.save(articleDto);

        if (responseResult.getCode() == 200) {
            updateStatus(wmNews, (short) 9, "审核通过 , 已发布");
        }

        return responseResult;
    }

    /**
     * 检测自定义敏感词汇
     *
     * @param wmNews
     * @param text
     * @return
     */
    private boolean handleSensitiveScan(WmNews wmNews, String text) {
        if (StringUtils.isBlank(text)) {
            return true;
        }
        Map<String, Integer> map = SensitiveWordUtil.matchWords(text);
        if (map.size() > 0) {
            updateStatus(wmNews, (short) 2, "文本内容包含敏感词汇");
            return false;
        }
        return true;
    }

    private boolean handleImagesScan(WmNews wmNews, List<String> images) {
        if (CollectionUtils.isEmpty(images)) {
            return true;
        }
        List<byte[]> bytes = new ArrayList<>();

        //从mio上下载图片信息,
       /* for (String url : images) {
            byte[] file = minIOTemplate.downLoadFile(url);
            bytes.add(file);
        }*/

        try {
            bytes = images.stream().map(image ->
                    minIOTemplate.downLoadFile(image)
            ).collect(Collectors.toList());
            //使用阿里云盾进行检测
            Map<String, String> map = aliyunGreenTemplate.greenImageScan(bytes);

            if ("block".equals(map.get("suggestion"))) {
                updateStatus(wmNews, (short) 2, "图片内容中包含违规信息");
                return false;
            }
            if ("review".equals(map.get("suggestion"))) {
                updateStatus(wmNews, (short) 3, "图片内容中包含不确定信息");
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            updateStatus(wmNews, (short) 3, "阿里云审核失败----" + e.getMessage());
            return false;
        }

        return true;
    }

    private boolean handleTextScan(WmNews wmNews, String text) {

        if (StringUtils.isBlank(text)) {
            return true;
        }

        //使用阿里进行文本检测
        Map<String, String> map = aliyunGreenTemplate.greenTextScan(text);

        try {
            //审核失败, 内容中包含违规信息
            if ("block".equals(map.get("suggestion"))) {
                updateStatus(wmNews, (short) 2, "文章内容中包含违规信息");
                return false;
            }
            //需要人工审核
            if ("review".equals(map.get("suggestion"))) {
                updateStatus(wmNews, (short) 3, "文章内容中包含不确定信息");
                return false;
            }
            return true;
        } catch (Exception e) {
            //审核失败
            e.printStackTrace();
            updateStatus(wmNews, (short) 3, "阿里云审核失败---" + e.getMessage());
            return false;

        }

    }

    private void updateStatus(WmNews wmNews, short status, String msg) {
        wmNews.setStatus(status);
        wmNews.setReason(msg);
        wmNewsDao.update(wmNews);
    }

    private Map<String, Object> extractTextAndImages(WmNews wmNews) {

        //装文本的
        StringBuilder sb = new StringBuilder();
        //装图片的
        List<String> images = new ArrayList<>();

        String content = wmNews.getContent();
        List<Map> list = JSON.parseArray(content, Map.class);


        //抽取正文中图片信息 与文本信息
        for (int i = 0; i < list.size(); i++) {
            Map map = list.get(i);
            if ("image".equals(map.get("type"))) {
                images.add((String) map.get("value"));
            }
            if ("text".equals(map.get("type"))) {
                sb.append(map.get("value")).append(",");
            }
        }
        //抽取封面中图片信息

        String wmNewsImages = wmNews.getImages();

        if (StringUtils.isNotBlank(wmNewsImages)) {
            String[] split = wmNewsImages.split(",");
            //把数组转成集合
            images.addAll(CollectionUtils.arrayToList(split));
        }

        //抽取标题文本信息
        sb.append(wmNews.getTitle());


        //封装结果
        Map<String, Object> map = new HashMap<>();
        map.put("text", sb.toString());
        map.put("image", images);


        return map;
    }
}
